---
--类名: ScriptManager.lua
--创建日期: 2017-12-14
--创建人: 陈小虎
--功能描述: 
--修改内容:
--修改日期:   
--修改人:      
--修改备注: 
--
local ScriptManager = class("ScriptManager")

function ScriptManager:ctor()
    cc(self):addComponent("components.behavior.EventProtocol"):exportMethods()

    self._scripts = {}
    self._dungeonSubScripts = {}
end

function ScriptManager:setActionNode(actionNode)
	self._actionNode = actionNode
end

function ScriptManager:getActionNode()
	return self._actionNode
end


function ScriptManager:parseScripts(taskConfig)
    if not taskConfig then
        return
    end

    local load = false
    local trackNpcArray = string.split(taskConfig.autoRun,";")
    for i,v in ipairs(trackNpcArray) do
        local npcId = tonumber(v)
        local npcConfig = NpcManager:getNpcConfigById(npcId)
        if npcConfig and npcConfig.ID then
            load = true
        end
    end

    if not load then return end

    local scriptName = taskConfig.dialog

    if not scriptName then
        return
    end

    local path = "scripts.taskscripts." .. scriptName
    print("path = ",path)
    local script = app:loadResScript(path)
    if script then
        St.parseInitEvents(script.initEvents)
        St.parseClickEvents(script)

        if script.areaEvents then
            local areaNpcConfig = NpcManager:getNpcConfigById(script.areaEvents.eventNpcId)
            if areaNpcConfig and areaNpcConfig.ID then
                local area = NpcManager:getArea(tonumber(script.areaEvents.eventNpcId))
                if area then
                    St.parseAreaEvents(script.areaEvents,area)
                        -- print("----------------- area:getId() = ",area:getId())
                else
                        -- print("----------------- area not exsit.")
                end
            end
        end
    else
        print("**************************************************")
        print("**************  " .. scriptName .. ".lua file is not exsit.****************")
        print("**************************************************")
    end
end

---
--@function 初始化任务事件脚本
--
function ScriptManager:initTaskEventsScript()
    local taskConfigs = TaskManager:getAllTaskConfigs()
    for _, taskConfig in ipairs(taskConfigs) do
        if taskConfig then
            if tonumber(taskConfig.type) ~= 3 then
                local taskLimitLevel = tonumber(taskConfig.minLevel) or 0
                if taskLimitLevel <= UD:getPlayer().level then
                    self:parseScripts(taskConfig)
                end
            end
        end
    end
end

function ScriptManager:updateTalkEvents(npcConfig, npc)
    -- print("1------- npcConfig.dialogScript = ",npcConfig.dialogScript)
    if npcConfig.dialogScript ~= nil then
        local path = "scripts.commonscripts." .. npcConfig.dialogScript
        local script = app:loadResScript(path)
        if script then
            local tNpcId = tonumber(npcConfig.ID)
            if not script._hasInit then
                script.init({npcId = tNpcId, npcUid = npc:getUid()})
                script._hasInit = true
            elseif script.clickEvents then -- script.clickEvents.eventNpcId ~= tNpcId then -- 不能用tNpcId作为判断条件，因为npcUid可能不相同
                script.clickEvents = {}
                script.init({npcId = tNpcId, npcUid = npc:getUid()})
            end
            if script.clickEvents and script.clickEvents.tasks then
                St.parseCommonTaskEvents(script.clickEvents.tasks,script.clickEvents.eventNpcId,npc)
            else
                St.parseCommonClickEvents(script.clickEvents,UD:getCurTaskId(),npc)
            end
            npc:setScriptFlag("talk",npcConfig.dialogScript)
        else
            npc:setScriptFlag("talk","none")
        end
    else
        local npcId = tonumber(npcConfig.ID)
        local npcResConfig = GD:queryNpcRes(npcId)
        if npcResConfig and (npcResConfig.talk or npcResConfig.randTalk) then
            npc:setScriptFlag("talk","talk")
            St.parseCommonConfigTalks(npcResConfig.talk,npcResConfig.randTalk,npcId,UD:getCurTaskId(),npc)
        else
            npc:setScriptFlag("talk","none")
        end
    end
end

function ScriptManager:initTalkEventsScript()
    
    local npcVec = NpcManager:getNpcVec()
    for k,npc in pairs(npcVec) do
        npc:clearEvents()
--        npc:deleteGuideAnimation()
        local id = npc:getId()
        self:initSingleTalkScripts(id)
    end

    local areaVec = NpcManager:getAreaVec()
    for k,area in pairs(areaVec) do
        area:clearEvents()
        local id = area:getId()
        self:initSingleTalkScripts(id)
    end

end

function ScriptManager:isTaskScriptLoaded(taskId)
    return (self._scripts[taskId] ~= nil) and true or false
end

function ScriptManager:getTaskScript(taskId)
    return self._scripts[taskId]
end

function ScriptManager:isHaveTaskEvents(taskId)
    local script = self:getTaskScript(taskId)
    local events
    if script then
        events = script.events
    end
    return events
end

function ScriptManager:parseTaskScripts(task)
    if not task then return end

    local taskId = task:getId()
    local scriptName = task:getConfig().createPar
    local bScriptName = task:getConfig().animationFinish
    local condition1Par1 = task:getConfig().condition1Par1

    if scriptName and tonumber(task:getConfig().taskCreate) == 4 then
        local path = "scripts.taskscripts." .. scriptName
        -- print("parseTaskScripts >>>> path = ",path)
        local script = app:loadResScript(path)
        if script then
            script.taskId = taskId
            local scripts = St.parseTaskEvents(script)
            if scripts then
                self._scripts[taskId] = scripts
            end
        end
    end

    if bScriptName then
        local path = "scripts.taskscripts." .. bScriptName
        -- print("parseTaskScripts >>>>2 path = ",path)
        local script = app:loadResScript(path)
        if script then
            script.taskId = taskId
            local scripts = St.parseTaskEvents(script)
            if scripts then
                if not self._scripts[taskId] then
                    self._scripts[taskId] = scripts
                end
                self._scripts[taskId].bEvents = scripts.events
                self._scripts[taskId].events = nil
            end
        end
    end

    -- dump(self._scripts)
end

function ScriptManager:getDungeonSubScript(dungeonSubId)
    if self._dungeonSubScripts[dungeonSubId] then 
        return self._dungeonSubScripts[dungeonSubId]
    end

    local bScriptName = "sub_".. dungeonSubId
    local path = "scripts.dungeonsub." .. bScriptName
    local script = app:loadResScript(path)
    if script then
        local scripts = St.parseTaskEvents(script)
        if scripts then
            self._dungeonSubScripts[dungeonSubId] = scripts
        end
    end
    return self._dungeonSubScripts[dungeonSubId]
end

function ScriptManager:updateNpcScripts(npc)
--    self:updateNpcEscortScripts(npc)
    self:updateNpcTalkScripts(npc)
--    self:updateNpcTaskScripts(npc)
end

function ScriptManager:updateNpcTalkScripts(npc)
    if not npc or npc:getScriptFlag("talk") then return end
    local config = npc:getConfig()
--    if self:isNeedTaskFinished(config) then
        npc:setMarkCondEnough(true)
        self:updateTalkEvents(config, npc)
--    else
--        npc:setMarkCondEnough(false)
--    end
end

function ScriptManager:initTaskScript()
    local tasks = UD:getTasks()
    for k,v in pairs(tasks) do
        self:updateTaskScript(v)
    end
end

function ScriptManager:updateTaskScript(task)
    if not task then return end
    if not task:isTaken() then return end
    if self:isTaskScriptLoaded(task:getId()) then return end
    self:parseTaskScripts(task)
end

function ScriptManager:initSingleTalkScripts(npcId)
    local npcConfig = NpcManager:getNpcConfigById(npcId)
    if npcConfig and npcConfig.ID then
        local npc = NpcManager:getNpcById(npcId)
        if npc then
--            self:updateEscortEvents(npcConfig, npc)
--            if self:isNeedTaskFinished(npcConfig) then
                npc:setMarkCondEnough(true)
                self:updateTalkEvents(npcConfig, npc)
--            else
--                npc:setMarkCondEnough(false)
--            end
            St.loadDungeonScript(npcConfig)
        end
    end
end

function ScriptManager:initSingleScripts(npc)
    if not npc then return end
    if npc.clearEvents then
        npc:clearEvents()
    end
--    if npc.deleteGuideAnimation then
--        npc:deleteGuideAnimation()
--    end
    local id = npc:getId()
    self:getActionNode():stopActionByTag(id)
    local action = cc.Sequence:create(cc.DelayTime:create(1),cc.CallFunc:create(function()
        self:initSingleTalkScripts(id)
        self:initTaskEventsScript()
    end))
    action:setTag(id)
    self:getActionNode():runAction(action)
end

function ScriptManager:initActivityScripts(npcId,script,aConfig)
    local npc = NpcManager:getNpcById(npcId)
    if npc then
        local function getEvents(npcId)
            if script ~= nil then
                local path = "scripts.activity." .. script
                local script = app:loadResScript(path)
                if script then
                    if not script._hasInit then
                        script.init({npcId = npcId, npcUid = npc:getUid()})
                        script._hasInit = true
                    elseif script.clickEvents and script.clickEvents.eventNpcId ~= npcId then
                        script.clickEvents = {}
                        script.init({npcId = npcId, npcUid = npc:getUid()})
                    end
                    St.parseCommonClickEvents(script.clickEvents,UD:getCurTaskId())
                end
            end
        end
        npc:clearEvents()
--        npc:deleteGuideAnimation()
        getEvents(npcId)
        npc:playActivityAction(aConfig)
    end
end

function ScriptManager:initScript()
    if not MapManager:getWorld() then return end

    NpcManager:deleteNotNeedMapSetBaseNpc()

    self:initTalkEventsScript()

--    NodeFactory:createGuideArrow()
end

function ScriptManager:refreshScripts()
    self:stopRefreshScriptsAction()
    self:initScript()
end

function ScriptManager:runRefreshScriptsAction()
    self:stopRefreshScriptsAction()
    if not self.m_refreshScriptsAction then
        self.m_refreshScriptsAction = cc.Sequence:create(
        	cc.DelayTime:create(2.0),
        	cc.CallFunc:create(function()
            self:refreshScripts()
        end))
        self:getActionNode():runAction(self.m_refreshScriptsAction)
    end
end

function ScriptManager:stopRefreshScriptsAction()
    if self.m_refreshScriptsAction then
        self:getActionNode():stopAction(self.m_refreshScriptsAction)
        self.m_refreshScriptsAction = nil
    end
end

return ScriptManager